﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Bouyei.Geo.GeoParsers
{
    using Geometries;
    /// <summary>
    /// .shx文件格式解析
    /// </summary>
    public class ShxParser : BaseFileParser
    {
        public ShxParser(string shxFile)
            :base(shxFile)
        {
        }

        public ShxInfo FromReader()
        {
            ShxInfo shx = new ShxInfo();

            using (FileStream fs = File.OpenRead(filename))
            using (BinaryReader reader = new BinaryReader(fs,encoding))
            {
                reader.ReadBytes(24);
                byte[] l = reader.ReadBytes(4);//<0代表数据长度未知

                shx.Length = (l[0] << 24) | (l[1] << 16) | (l[2] << 8) | l[3];
                shx.Version = reader.ReadInt32();
                shx.geometryType = (GeoType)reader.ReadInt32();

                shx.xMin = reader.ReadDouble();
                shx.yMin = reader.ReadDouble();
                shx.xMax = reader.ReadDouble();
                shx.yMax = reader.ReadDouble();
                int blockCnt = (int)(fs.Length - 100) >> 3;
                shx.Blocks = new List<ShxBlock>(blockCnt);

                while (reader.PeekChar() != -1)
                {
                    byte[] b = reader.ReadBytes(4);
                    int offset = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];

                    b = reader.ReadBytes(4);
                    int record = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];

                    shx.Blocks.Add(new ShxBlock()
                    {
                        Offset = offset,
                        Length = record
                    });
                }
            }

            return shx;
        }
    }

    public class ShxInfo
    {
        public int Length { get; set; }

        public int Version { get; set; }

        public  GeoType geometryType { get; set; }

        public double xMin { get; set; }

        public double yMin { get; set; }

        public double xMax { get; set; }

        public double yMax { get; set; }

        public List<ShxBlock> Blocks;
    }

    public class ShxBlock
    {
        public int Offset { get; set; }

        public int Length { get; set; }
    }
}
